import { env } from "@/config/config";
import { reactive } from "vue";

interface IInitInnerAudio {
  id: string;
  src: string;
  loop?: boolean;
  startTime?: number;
  autoplay?: boolean;
  obeyMuteSwitch?: boolean;
}
const data = {
  id: "",
  current: 0,
  duration: 0,
  setCrt: true,
  status: {
    playing: false, // 播放
    seeking: false, // 拖动
    waiting: false, // 加载
  },
};
const _data = JSON.parse(JSON.stringify(data));
const state = reactive(_data) as typeof data;
let innerAudio: ReturnType<typeof uni.createInnerAudioContext> | null;
function initInnerAudio(options: IInitInnerAudio) {
  destroyAudio();
  innerAudio = uni.createInnerAudioContext();
  const {
    src,
    id = "",
    loop = false,
    startTime = 0,
    autoplay = false,
    obeyMuteSwitch = false,
  } = options;
  innerAudio.obeyMuteSwitch = obeyMuteSwitch;
  innerAudio.startTime = startTime;
  innerAudio.autoplay = autoplay;
  innerAudio.loop = loop;
  innerAudio.src = src;
  state.id = id;
  listeningEvent();
}
function listeningEvent() {
  innerAudio?.onTimeUpdate(() => {
    if (!state.status.seeking && state.setCrt) {
      state.current = innerAudio?.currentTime || 0;
    }
  });
  innerAudio?.onPlay(() => {
    state.status.waiting = false;
    if (state.status.seeking) {
      seekAudio(state.current);
    } else {
      state.status.seeking = false;
    }
  });
  innerAudio?.onPause(() => {
    if (state.status.seeking && state.status.playing) {
      innerAudio?.seek(state.current);
    } else {
      state.status.seeking = false;
    }
  });
  innerAudio?.onWaiting(() => {
    state.status.waiting = true;
    if (!innerAudio?.paused) innerAudio?.pause();
  });
  innerAudio?.onCanplay(() => {
    state.status.waiting = false;
    state.duration = innerAudio.duration || 0;
    if (state.status.playing && !state.status.seeking) playAudio(state.setCrt);
  });
  innerAudio?.onSeeked(() => {
    if (state.status.seeking) {
      state.status.seeking = false;
      if (state.status.playing && !state.status.waiting) playAudio(state.setCrt);
    }
  });
  innerAudio?.onStop(() => {});
  innerAudio?.onEnded(() => {
    // state.current = 0;
    uni.$emit("audioPlayStop");
    state.status = JSON.parse(JSON.stringify(data.status));
  });
  innerAudio?.onError((error) => {
    destroyAudio();
    if (env === "dev") console.log(error, "error");
  });
}
function playAudio(setCrt: boolean = true) {
  state.setCrt = setCrt;
  state.status.playing = true;
  if (innerAudio?.paused) innerAudio.play();
}
function pauseAudio() {
  state.status.playing = false;
  if (!innerAudio?.paused) innerAudio?.pause();
}
function stopAudio() {
  innerAudio?.stop();
  state.current = 0;
  state.duration = 0;
  state.status = JSON.parse(JSON.stringify(data.status));
}
function seekAudio(value: number) {
  if (value <= 0) value = 0;
  if (value >= state.duration) value = state.duration;
  state.status.seeking = true;
  state.status.playing = true;
  state.current = value;
  if (!innerAudio?.paused) {
    innerAudio?.pause();
  } else {
    if (!state.status.waiting) playAudio(state.setCrt);
  }
}
function destroyAudio() {
  innerAudio?.stop();
  innerAudio?.destroy();
  const _data = JSON.parse(JSON.stringify(data));
  Object.assign(state, _data);
}

export { state as audioState, initInnerAudio, playAudio, pauseAudio, stopAudio, destroyAudio };
